#include "hcpp/ptp2_task.h"
//#include "hcpp/ptp2_log.h"

#include <string.h>

static bool ptp2_task_setup(ptp2_task_t *this, const char *name, ptp2_task_execute_fn execute, void *ref, void *param);
static void ptp2_task_destructor(void *ptr);

static class_info_t class_info = {
    .size        = sizeof(ptp2_task_t),
    .destructor  = ptp2_task_destructor,
    .mem_alloc   = malloc,
    .mem_free    = free
};

ptp2_task_t *
ptp2_task_new(const char *name, ptp2_task_execute_fn execute, void *ref, void *param)
{
    ptp2_task_t *this;

    if ((this = object_new(&class_info)) == NULL) {
        return NULL;
    }

    if (!ptp2_task_setup(this, name, execute, ref, param)) {
        return NULL;
    }

    return this;
}

bool
ptp2_task_init(ptp2_task_t *this, const char *name, ptp2_task_execute_fn execute, void *ref, void *param)
{
    object_init(this, &class_info);
    return ptp2_task_setup(this, name, execute, ref, param);
}

static bool
ptp2_task_setup(ptp2_task_t *this, const char *name, ptp2_task_execute_fn execute, void *ref, void *param)
{
    strncpy((char *) this->name, (const char *) name, sizeof(this->name));

    this->name[sizeof(this->name) - 1] = '\0';
    this->execute                      = execute;
    this->ref                          = ref;
    this->param                        = param;

    if (this->ref   != NULL) object_retain(this->ref);
    if (this->param != NULL) object_retain(this->param);

    return true;
}

static void
ptp2_task_destructor(void *ptr)
{
    ptp2_task_t *this = (ptp2_task_t *) ptr;

    if (this->ref   != NULL) object_release(this->ref);
    if (this->param != NULL) object_release(this->param);

    //PTP2_LOG_PRINTLN(PTP2_LOG_TASK, PTP2_LOG_DEBUG, ("ptp2_task_destructor(%08X)\n", (unsigned int) this));
}




